/**
 * Created by enixjin on 1/3/17.
 */
import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http";
import "rxjs/add/observable/throw";
import "rxjs/add/operator/catch";
import "rxjs/add/operator/map";
import {Observable} from "rxjs/Observable";
import * as constants from "../constants";
import {BaseModule} from "../entity/BaseModule";

export abstract class BaseService<T extends BaseModule> {
    protected _serviceServerBaseUrl: string = constants.DOMAIN_SERVER_URL;

    public abstract getServiceUrl(): string;

    constructor(protected http: HttpClient) {
    }

    protected handleError(error) {
        let errorMessage = error.message;
        if (error.error) {
            errorMessage += ":" + error.error;
        }
        switch (error.status) {
            case 401:
                return Observable.throw("invalid token");
            default:
                return Observable.throw(errorMessage);
        }
    }

    protected getJsonHeader(params?: HttpParams) {
        let headers = new HttpHeaders();
        headers = headers.append("Content-Type", "application/json");
        headers = headers.append("jwt", localStorage.getItem("token"));
        if (params) {
            return {headers, params};
        } else {
            return {headers};
        }
    }

    protected getLoginUser() {
        return JSON.parse(localStorage.getItem("loginUser"));
    }

    protected getJsonHeaderWithoutJWT(params?: HttpParams) {
        let headers = new HttpHeaders();
        headers = headers.append("Content-Type", "application/json");
        if (params) {
            return {headers, params};
        } else {
            return {headers};
        }
    }

    delete(id: number) {
        return this.http.delete(this.getServiceUrl() + "/" + id, this.getJsonHeader())
            .catch(this.handleError);
    }

    create(domainObject: T) {
        return this.http.post(this.getServiceUrl(), JSON.stringify(domainObject), this.getJsonHeader())
            .catch(this.handleError);
    }

    update(domainObject: T) {
        return this.http.put(this.getServiceUrl() + "/" + domainObject.id, JSON.stringify(domainObject), this.getJsonHeader())
            .catch(this.handleError);
    }

    batchUpdate(domainObject: T[]) {
        return this.http.put(this.getServiceUrl() + "/batchUpdate", JSON.stringify(domainObject), this.getJsonHeader())
            .catch(this.handleError);
    }

    get(id: number) {
        return this.http.get<T>(this.getServiceUrl() + "/" + id, this.getJsonHeader())
            .catch(this.handleError);
    }

    list() {
        return this.http.get<T[]>(this.getServiceUrl(), this.getJsonHeader())
            .catch(this.handleError);
    }

    search(params: HttpParams) {
        return this.http.get<T[]>(this.getServiceUrl() + "/search/like", this.getJsonHeader(params))
            .catch(this.handleError);
    }

    searchLikeOr(params: HttpParams) {
        return this.http.get<T[]>(this.getServiceUrl() + "/search/like/or", this.getJsonHeader(params))
            .catch(this.handleError);
    }
}
